package com.ruoyi.web.controller.common;

import io.micrometer.core.annotation.Timed;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.DistributionSummary;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.ClientResponse;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

@Component
public class ThirdPartyHttpClientWithHistogram {

    private final WebClient webClient;
    private final Counter callCounter;
    private final Timer callTimer;
    private final Timer callHttpTimer;
    private final DistributionSummary responseSizeSummary;

    public ThirdPartyHttpClientWithHistogram(WebClient.Builder webClientBuilder, MeterRegistry meterRegistry) {
        this.webClient = webClientBuilder.build();
        // 定义调用量计数器
        this.callCounter = meterRegistry.counter("third_party_http_calls");
        // 定义调用延迟计时器（使用直方图）
        this.callTimer = Timer.builder("third_party_http_call_latency")
                .publishPercentiles(0.5, 0.95, 0.99) // 发布 50%、95% 和 99% 的百分位数
                .register(meterRegistry);
        // 定义调用延迟计时器（使用直方图）
        this.callHttpTimer = Timer.builder("httpInvoker")
                .publishPercentiles(0.5, 0.95, 0.99) // 发布 50%、95% 和 99% 的百分位数
                .register(meterRegistry);
        // 定义响应大小直方图
        this.responseSizeSummary = DistributionSummary.builder("third_party_http_response_size")
                .publishPercentiles(0.5, 0.95, 0.99)
                .register(meterRegistry);
    }

    public Mono<String> callThirdPartyApi(String url) {
        // 记录调用量
        callCounter.increment();
        return callTimer.record(() -> webClient.get()
                .uri(url)
                .exchangeToMono(response -> {
                    // 记录响应大小
                    responseSizeSummary.record(response.headers().contentLength().orElse(0L));
                    return response.bodyToMono(String.class);
                }));
    }

    /**
     * 通过普罗米修斯-注解-监控第三方API调用
     * 异步调用第三方API
     * @param url
     * @return
     */
    @Async
    public Mono<String> asyncCallThirdPartyApi(String url) {
        return callHttpTimer.record(()->webClient.get()
                .uri(url).exchangeToMono(response -> {
                    return response.bodyToMono(String.class);
                }));
    }
}
